package com.tongtong.stsuserapi.filter;

import com.tongtong.stscommon.utils.JwtUtil;
import com.tongtong.stscommon.utils.RedisCache;
import com.tongtong.stsuserapi.pojo.authentication.LoginManager;
import com.tongtong.stsuserapi.pojo.authentication.LoginUser;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Objects;

/**
 * JWT过滤器
 * 用于token鉴权
 */
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

	@Autowired
	RedisCache redisCache;

	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {

		// 获取token
		String token = request.getHeader("token");
		if (! StringUtils.hasText(token)) {
			// 直接放行
			filterChain.doFilter(request, response);
			return;
		}

		// 解析token
		String parsedJwt;
		try {
			Claims claims = JwtUtil.parseJWT(token);
			parsedJwt = claims.getSubject();
		} catch (Exception e) {
			//将异常分发到JwtException控制器
			request.getRequestDispatcher("/illegalJwtException").forward(request, response);
			return;
		}

		// 根据解析的角色信息进行认证
		String role = parsedJwt.split(":")[0];
		if(role.equals("user")) {
			String userid = parsedJwt.split(":")[1];
			// 从Redis中获取用户信息
			String redisKey = "login:user:" + userid;
			LoginUser loginUser = redisCache.getCacheObject(redisKey);
			if(Objects.isNull(loginUser)) {
				//将异常分发到JwtException控制器
				request.getRequestDispatcher("/expiredJwtException").forward(request, response);
				return;
			}

			// 存入SecurityContextHolder，便于后续过滤器获取认证成功信息
			UsernamePasswordAuthenticationToken authenticationToken =
					new UsernamePasswordAuthenticationToken(loginUser,userid,loginUser.getAuthorities());
			SecurityContextHolder.getContext().setAuthentication(authenticationToken);

		} else if(role.equals("manager")) {
			String managerId = parsedJwt.split(":")[1];
			// 从Redis中获取用户信息
			String redisKey = "login:manager:" + managerId;
			LoginManager loginManager = redisCache.getCacheObject(redisKey);
			if(Objects.isNull(loginManager)) {
				request.getRequestDispatcher("/expiredJwtException").forward(request, response);
				return;
			}

			UsernamePasswordAuthenticationToken authenticationToken =
					new UsernamePasswordAuthenticationToken(loginManager,managerId,loginManager.getAuthorities());
			SecurityContextHolder.getContext().setAuthentication(authenticationToken);
		}

		// 放行
		filterChain.doFilter(request,response);
	}
}